package org.abettor.jroa.impl;

import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.net.Socket;

import org.abettor.jroa.Accessible;
import org.abettor.jroa.Connection;

/**
 * <p>The implemention of the <i>Connection</i> interface
 * implemented by <i>Socket</i>.</p>
 * 
 * @see org.abettor.jroa.Connection
 * @see java.net.Socket
 * 
 * @author <a href="http://www.abettor.org/" target="_blank">abettor</a>
 *
 */
public class SocketConnection implements Connection
{
	private Socket socket;

	/**
	 * Construct a <i>Connection</i> object with a <i>Socket</i> object.
	 * @param socket A connected <i>Socket</i> object.
	 */
	public SocketConnection(Socket socket)
	{
		this.socket = socket;
	}

	/**
	 * @see org.abettor.jroa.Connection#fetchObject()
	 * @throws ClassNotFoundException 
	 */
	public Accessible fetchObject() throws IOException, ClassNotFoundException
	{
		InputStream is = socket.getInputStream();
		ObjectInputStream ois = new ObjectInputStream(is);
		Accessible obj = (Accessible) ois.readObject();
		if(obj.isFrozen())
		{
			obj.thaw();
		}

		return obj;
	}

	/**
	 * @see org.abettor.jroa.Connection#isClosed()
	 */
	public boolean isClosed()
	{
		if(socket.isClosed())
		{
			return true;
		}
		else if(! socket.isConnected())
		{
			return true;
		}

		return false;
	}

	/**
	 * @see org.abettor.jroa.Connection#postObject(Accessible)
	 */
	public void postObject(Accessible obj) throws IOException
	{
		obj.freeze();
		OutputStream os = socket.getOutputStream();
		ObjectOutputStream oos = new ObjectOutputStream(os);
		oos.writeObject(obj);
	}

	/**
	 * @see java.io.Closeable#close()
	 */
	public void close() throws IOException
	{
		if(! socket.isClosed())
		{
			socket.close();
		}
	}
}
